#!/bin/bash

####################################### CONFIGURACION ########################################

# Tiempo de ciclo del demonio (seg)
t_refresco=2

# Constantes
readonly TIPO_RESERVA_PRODUCCION=1
readonly TIPO_RESERVA_SALA=2
readonly TIPO_INVITACION=3
readonly TIPO_INVALIDO=4

# DEBUG: setear en 1 para imprimir por pantalla mensajes de debug
DEBUG=0

# Comandos externos
MOVER_B="$BINDIR/Mover_B.sh"
GRABAR_L="$BINDIR/Grabar_L.sh Recibir_B"
RESERVAR_B="$BINDIR/Reservar_B.sh"

# Archivos
a_salas=$MAEDIR/salas.mae
a_obras=$MAEDIR/obras.mae

##############################################################################################




#------------------------------------------------------------------------------------------------#
# Descripcion:  Verifica la validez de los datos contenidos en el nombre del archivo pasado 
# por parametro usando los archivos maestros.
# 
# Parametros: 
# 1: nombre de archivo
# 2: tipo de reserva ["obra"|"sala"]
# 3: escribir en log [1: grabar log | 0: no grabar log]
#
# Retorno:
# 0: valido
# 1: invalido
# 2: error en parametros
#------------------------------------------------------------------------------------------------#
function validar_reserva {
 nombre_archivo="$1"; tipo_reserva=$2; log=$3

 debug "Validando reserva: $nombre_archivo..." 
 case $tipo_reserva in
  "obra") validar_obra "$nombre_archivo";;
  "sala") validar_sala "$nombre_archivo";;
  *) debug "Error en parametros"; return 2;; 
 esac
 
 error=$?

 if [ $log -eq 1 ]; then
  case $error in
   0) $GRABAR_L I "Se ha procesado $tipo_reserva correctamente. Archivo: $nombre_archivo";;
   1) $GRABAR_L E "Se ha procesado $tipo_reserva invalida (id inexistente). Archivo: $nombre_archivo";;
   2) $GRABAR_L E "Se ha procesado $tipo_reserva invalida (id existente, mail inexistente). Archivo: $nombre_archivo";;
  esac
 fi

 [ $error -ne 0 ] && return 1 
return 0
}

#------------------------------------------------------------------------------------------------#
# Descripcion:  Verifica la validez de los datos contenidos en el nombre del archivo pasado 
# por parametro usando los archivos maestros.
# PRE: debe verificarse previamente que el id sea par (direccionado desde tipo_arribo).
# Parametros: 
# 1: nombre de archivo
#
# Retorno:
# 0: valida
# 1: sala inexistente
# 2: sala encontrada, correo incorrecto
#------------------------------------------------------------------------------------------------#
function validar_sala {
  read id_param email_param token_param <<< `echo "$nombre_archivo" | sed -n 's/^\(.*\)-\(.*\)-\(.*\)$/\1\ \2 \3/p'`
  salir=1;  mail_encontrado=1; sala_encontrada=1
  while [ $salir -eq 1 ] && read sala; do
    debug "Archivo Salas: $sala"
    read id email_teatro <<< `echo $sala | awk -F';' '{ printf("%s %s", $1, $6) }'`
    if [ $id_param == $id ]; then
        sala_encontrada=0
        if [ $email_param == $email_teatro ]; then
         mail_encontrado=0
        fi
        salir=0
    fi
  done < $a_salas

  if [ $sala_encontrada -eq 0 ]; then
      [ $mail_encontrado -eq 1 ] && return 2
  else
      return 1
  fi
return 0
}

#------------------------------------------------------------------------------------------------#
# Descripcion:  Verifica la validez de los datos contenidos en el nombre del archivo pasado 
# por parametro usando los archivos maestros.
# PRE: debe verificarse previamente que el id sea impar (direccionado desde tipo_arribo).
# Parametros: 
# 1: nombre de archivo
#
# Retorno:
# 0: valida
# 1: obra inexistente
# 2: obra encontrada, correo incorrecto
#------------------------------------------------------------------------------------------------#
function validar_obra {
  read id_param email_param token_param <<< `echo "$nombre_archivo" | sed -n 's/^\(.*\)-\(.*\)-\(.*\)$/\1\ \2 \3/p'`
 
  salir=1; mail_encontrado=1; obra_encontrada=1
  while [ $salir -eq 1 ] && read obra; do
    debug "Archivo Obra: $obra"
    read id email_prod_gral email_prod_ejec <<< `echo $obra | awk -F';' '{ printf("%s %s %s", $1, $3, $4) }'`
    if [ $id_param == $id ]; then 
        obra_encontrada=0
  if [ $email_param == $email_prod_gral -o $email_param == $email_prod_ejec ]; then
         mail_encontrado=0
        fi
        salir=0
    fi  
  done < $a_obras 

  if [ $obra_encontrada -eq 0 ]; then
      [ $mail_encontrado -eq 1 ] && return 2
  else 
      return 1
  fi
return 0
}

#------------------------------------------------------------------------------------------------#
# Determina el tipo de archivo a partir del nombre de archivo pasado por parametro.
# El primer parametro es el tipo de msj que se pasa a la funcion que loguea
# Parametros: 
# 1: Nombre de archivo
#
# Tipo reserva: ID de la OBRA-CORREO-xxx 
#     ID: impar para reserva de produccion, par para sala
# Tipo invitacion: Referencia Interna del Solicitante.inv
#        Ref: cadena sin espacios ni guiones
# Tipo invalido: cualquiera que no cumpla con las anteriores caracteristicas.
# Retorno: constantes TIPO_*
# NOTAS: 
# 1) Esta funcion solamente verifica el formato correcto de los datos pero
# no valida que sean validos. Esto lo hacen las funciones validar_* correspon-
# diente al tipo de arribo.
# 2) El token final del nombre puede contener guion bajo (figura en el ejemplo)
#------------------------------------------------------------------------------------------------#
function tipo_arribo {
 nombre_archivo=$1
 
 tipo=$TIPO_INVALIDO
 p_mail="[A-Za-z0-9.]"

if [[ $nombre_archivo =~ ^[0-9A-Za-z]*\.inv$ ]]; then
        tipo=$TIPO_INVITACION
 else
    read id email token <<< `echo $nombre_archivo | sed -n "s/^\([0-9]*\)-\(.*\)-\([^\ -]*\)\$/\1\ \2 \3/p"`
     
    if [ ! -z $id ] && [ ! -z $email ] && [ ! -z $token ] &&
       [[ $email =~ $p_mail*@$p_mail*\.[a-z]* ]]; then
      if [[ 1 -eq $id%2 ]]; then
        tipo=$TIPO_RESERVA_PRODUCCION
      else
        tipo=$TIPO_RESERVA_SALA
      fi
    fi
 fi
echo $tipo
}

function debug {
 [ $DEBUG -eq 1 ] && echo DEBUG: $@
}

#------------------------------------------------------------------------------------------------#
# Descripcion: valida el archivo de entrada y lo coloca en el directorio correspondiente. 
# Parametros: 
# 1: ruta completa al archivo
#
# Retorno:
# 0: si el archivo es valido
# 1: 1 si es invalido
#------------------------------------------------------------------------------------------------#
function procesar {
 path_completo=$1
 nombre_archivo=`basename $path_completo`

 case $(tipo_arribo $nombre_archivo) in
        $TIPO_RESERVA_PRODUCCION)
                debug "Procesando archivo reserva obra $nombre_archivo..."
                if validar_reserva $nombre_archivo 'obra' 1; then                      
                        debug "Moviendo reserva de obra a $ACEPDIR"
                        bash $MOVER_B $path_completo $ACEPDIR
                else
                        debug "Moviendo reserva de obra a $RECHDIR"
                        bash $MOVER_B $path_completo $RECHDIR
                fi
                ;;                
        $TIPO_RESERVA_SALA)
                debug "Procesando archivo reserva de sala $nombre_archivo..."
                if validar_reserva $nombre_archivo 'sala' 1;then
                        debug "Moviendo reserva de sala a $ACEPDIR"
                        bash $MOVER_B $path_completo $ACEPDIR
                else
                        debug "Moviendo reserva de sala a $RECHDIR"
                        bash $MOVER_B $path_completo $RECHDIR
                fi
                ;;
        $TIPO_INVITACION)
                debug "Procesando archivo de invacion $nombre_archivo..."
                $GRABAR_L I "Se ha procesado con exito invitacion: $nombre_archivo"
                debug "Moviendo invitacion a $REPODIR"
                bash $MOVER_B $path_completo $REPODIR
                ;;
        $TIPO_INVALIDO)
                $GRABAR_L E " Se rechaza archivo por tener mal el nombre. Archivo $nombre_archivo"
                debug "Moviendo archivo invalido a $RECHDIR"
                bash $MOVER_B $path_completo $RECHDIR
                ;;
 esac
}


#------------------------------------------------------------------------------------------------#
# Descripcion: verifica si Reservar_B.sh esta ejecutandose.
#
# Retorno:
# 0: si Reservar_B.sh esta ejecutandose
# 1: si Reservar_B.sh no esta ejecutandose
#------------------------------------------------------------------------------------------------#
function reservarEjecutando {
  cant=$(ps ax | grep 'Reservar_B.sh' | grep -v "grep" | wc -l);
  if [ $cant -eq 0 ]; then
    return 1
  fi
return 0
}

#------------------------------------------------------------------------------------------------#
# Descripcion: verifica si el nombre de archivo pasado por parametro contiene espacios.
#
# Retorno:
# 0: tiene espacios
# 1: no tiene espacios
#------------------------------------------------------------------------------------------------#
function tieneEspacios {
  cant=`echo "$1" | grep '[[:space:]]'|wc -l`
  if [ $cant -eq 0 ];then
    return 1
  fi
return 0
}

#------------------------------------------------------------------------------------------------#
# Descripcion: mueve a RECHDIR todos los arribos que sean de texto o contengan espacios.
#------------------------------------------------------------------------------------------------#
function descartarArchivosDeTexto {
   vIFS=$IFS; IFS=$'\n'
   for a_arribo in `ls $ARRIDIR`; do
    if tieneEspacios "$a_arribo" || 
      [[ "$a_arribo" =~ ^[0-9A-Za-z]*\.txt$ ]]; then
      IFS=$vIFS
      $GRABAR_L E "Se descarta $a_arribo por ser archivo de texto"
      $MOVER_B "$ARRIDIR/$a_arribo" $RECHDIR
      IFS=$'\n'
    fi    
   done
   IFS=$vIFS
}

#------------------------------------------------------------------------------------------------#
# Descripcion: inicia el demonio
# PRE: el ambiente debe estar inicializado.
#------------------------------------------------------------------------------------------------#
function iniciar_demonio {
    contador_de_ciclos=0
    while(true) do
      if [ "$(ls -A $ARRIDIR)" ];then
        descartarArchivosDeTexto
        for a_arribo in `ls $ARRIDIR`; do
         procesar "$ARRIDIR/$a_arribo"
        done
      fi
      if [ "$(ls -A $ACEPDIR)" ];then
        if reservarEjecutando;then
          $GRABAR_L W "Se recibieron nuevos arribos. Reservar_B.sh aun esta ejecutandose. Esperando..."
        else
          bash $RESERVAR_B &
          $GRABAR_L I "Se está corriendo el ciclo nro. $contador_de_ciclos"
          $GRABAR_L I "Reservar_B ejecutando con PID: $!"
          let contador_de_ciclos+=1
        fi
      fi
    sleep $t_refresco
    done
}

iniciar_demonio
